﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Jt808CommandEncoder.Utils
{
    public class CommonUtil
    {
        /// <summary>
        /// Hex format string to byte array
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string hexString)
        {
            try
            {
                hexString = hexString.Replace("\n", "").Replace("\r\n", "").Trim();
                hexString = Regex.Replace(hexString, @".{2}", "$0 ");
                //Split the string with ' ' and remove empty characters
                string[] chars = hexString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                byte[] returnBytes = new byte[chars.Length];
                //Character by character becomes hexadecimal byte data
                for (int i = 0; i < chars.Length; i++)
                {
                    returnBytes[i] = Convert.ToByte(chars[i], 16);
                }
                return returnBytes;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// Short to Bytes
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static byte[] ShortToBytes(short number)
        {
            byte byte2 = (byte)(number >> 8);
            byte byte1 = (byte)(number & 255);
            byte[] bytes = new byte[2];
            bytes[0] = byte1;
            bytes[1] = byte2;
            //这里需要进行反转，否则组包的时候就是低位在前高位在后了
            return bytes.Reverse().ToArray();
        }

        /// <summary>
        /// Int32 to Bytes
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static byte[] Int32ToBytes(Int32 number)
        {
            byte[] bytes = new byte[4];
            bytes[0] = (byte)(number & 0xFF);
            bytes[1] = (byte)((number & 0xFF00) >> 8);
            bytes[2] = (byte)((number & 0xFF0000) >> 16);
            bytes[3] = (byte)((number >> 24) & 0xFF);
            //这里需要进行反转，否则组包的时候就是低位在前高位在后了
            return bytes.Reverse().ToArray();
        }

        /// <summary>
        /// Calculate check code
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte xor(List<byte> bytes)
        {
            int checksum = 0;
            foreach (byte b in bytes)
            {
                checksum ^= b;
            }
            return (byte)(checksum & 0xff);
        }

        /// <summary>
        /// Escape
        /// </summary>
        /// <param name="inBytes"></param>
        /// <returns></returns>
        public static byte[] escape(List<byte> inBytes)
        {
            List<byte> outBytes = new List<byte>();
            foreach (byte b in inBytes)
            {
                if (b == 0x7E)
                {
                    outBytes.AddRange(HexStringToBytes("7D02"));
                }
                else if (b == 0x7D)
                {
                    outBytes.AddRange(HexStringToBytes("7D01"));
                }
                else
                {
                    outBytes.Add(b);
                }
            }
            return outBytes.ToArray();
        }

        /// <summary>
        /// Convert byte array to hex string
        /// </summary>
        /// <param name="byteDatas"></param>
        /// <returns></returns>
        public static string ByteToHexStr(byte[] byteDatas)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < byteDatas.Length; i++)
            {
                builder.Append(string.Format("{0:X2}", byteDatas[i]));
            }
            return builder.ToString().Trim();
        }

        /// <summary>
        /// IP supplement 0; The domain name is returned directly
        /// </summary>
        /// <param name="Ip"></param>
        /// <returns></returns>
        public static string IpPixZore(string Ip)
        {
            string[] strArray = Ip.Split('.');
            if (strArray.Length == 4)
            {
                try
                {
                    foreach (string item in strArray)
                    {
                        if (!(int.Parse(item) >= 0 && int.Parse(item) <= 255))
                        {
                            return Ip;
                        }
                    }
                }
                catch
                {
                    return Ip;
                }
                string resultIp = string.Empty;
                foreach (string item in strArray)
                {
                    resultIp += item.PadLeft(3, '0') + ".";
                }
                return resultIp = resultIp.Trim('.');
            }
            else
            {
                return Ip;
            }
        }
    }
}
